home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / utils / shell / cdialog-.9a / cdialog- / cdialog-0.9a / tailbox.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-15  |  9.2 KB  |  367 lines

  1. /*
  2.  *  tailbox.c -- implements the tail box
  3.  *
  4.  *  AUTHOR: Pasquale De Marco (demarco_p@abramo.it)
  5.  *
  6.  *  This program is free software; you can redistribute it and/or
  7.  *  modify it under the terms of the GNU General Public License
  8.  *  as published by the Free Software Foundation; either version 2
  9.  *  of the License, or (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. #include "dialog.h"
  22.  
  23. static void last_lines(int n);
  24. static void print_page(WINDOW *win, int height, int width);
  25. static void print_last_page(WINDOW *win, int height, int width);
  26. static void print_line(WINDOW *win, int row, int width);
  27. static char *get_line(void);
  28.  
  29.  
  30. static int hscroll = 0, page_length, old_hscroll = 0, end_reached;
  31. static FILE *fd;
  32.  
  33. int can_quit = 0;
  34.  
  35. void signal_tailbg(int sig) { /* __sighandler_t */
  36.   if (sig == 15) can_quit=1;
  37. }
  38.  
  39. /*
  40.  * Display text from a file in a dialog box, like in a "tail -f".
  41.  */
  42. int dialog_tailbox(const char *title, const char *file, int height, int width)
  43. {
  44.   int i, x, y, cur_x, cur_y, key = 0;
  45.   WINDOW *dialog, *text;
  46.   char ch;
  47.  
  48.   auto_sizefile(file, &height, &width, 2, 12);
  49.   print_size(height, width);
  50.   ctl_size(height, width);
  51.  
  52.   /* Open input file for reading */
  53.   if ((fd = fopen(file, "rb")) == NULL)
  54.     exiterr("\nCan't open input file in dialog_tailbox().\n");
  55.  
  56.   if (begin_set == 1) {
  57.     x = begin_x;
  58.     y = begin_y;
  59.   } else {
  60.     /* center dialog box on screen */
  61.     x = (SCOLS - width)/2;
  62.     y = (SLINES - height)/2;
  63.   }
  64.  
  65. #ifdef HAVE_NCURSES
  66.   if (use_shadow)
  67.     draw_shadow(stdscr, y, x, height, width);
  68. #endif
  69.   dialog = newwin(height, width, y, x);
  70.   mouse_setbase (x, y);
  71.   keypad(dialog, TRUE);
  72.  
  73.   /* Create window for text region, used for scrolling text */
  74.   text = subwin(dialog, height-4, width-2, y+1, x+1);
  75.   keypad(text, TRUE);
  76.  
  77.   draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
  78.  
  79.   wattrset(dialog, border_attr);
  80.   wmove(dialog, height-3, 0);
  81.   waddch(dialog, ACS_LTEE);
  82.   for (i = 0; i < width-2; i++)
  83.     waddch(dialog, ACS_HLINE);
  84.   wattrset(dialog, dialog_attr);
  85.   waddch(dialog, ACS_RTEE);
  86.   wmove(dialog, height-2, 1);
  87.   for (i = 0; i < width-2; i++)
  88.     waddch(dialog, ' ');
  89.  
  90.   if (title != NULL) {
  91.     wattrset(dialog, title_attr);
  92.     wmove(dialog, 0, (width - strlen(title))/2 - 1);
  93.     waddch(dialog, ' ');
  94.     waddstr(dialog, title);
  95.     waddch(dialog, ' ');
  96.   }
  97.   print_button(dialog, " EXIT ", height-2, width/2-4, TRUE);
  98.     
  99.   wmove(dialog, height-4, 2);
  100.   
  101.   wnoutrefresh(dialog);
  102.   getyx(dialog, cur_y, cur_x);    /* Save cursor position */
  103.  
  104.   /* Print last page of text */
  105.   attr_clear(text, height-4, width-2, dialog_attr);
  106.   print_last_page(text, height-5, width-2);
  107.   wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  108.   wrefresh_lock(dialog);
  109.  
  110.   /* nodelay(dialog, TRUE);  with this it takes much more cpu time*/
  111.   wtimeout(dialog, WTIMEOUT_VAL);
  112.  
  113.   while (key != ESC) {
  114.     key = wgetch(dialog);
  115.     switch (key) {
  116.       case ERR:
  117.         ch=getc(fd);
  118.         ungetc(ch, fd);
  119.         if ((ch != -1) || (hscroll != old_hscroll)) {
  120.           old_hscroll=hscroll;
  121.           print_last_page(text, height-5, width-2);
  122.           wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  123.           wrefresh_lock(dialog);
  124.         }
  125.         ctl_idlemsg(dialog);
  126.         break;
  127.       case 'E':    /* Exit */
  128.       case 'e':
  129.       case '\n':
  130.         delwin(dialog);
  131.         fclose(fd);
  132.         return 0;
  133.       case '0':    /* Beginning of line */
  134.       case 'H':    /* Scroll left */
  135.       case 'h':
  136.       case KEY_LEFT:
  137.         if (hscroll > 0) {
  138.           if (key == '0')
  139.             hscroll = 0;
  140.           else
  141.             hscroll--;
  142.         }
  143.         break;
  144.       case 'L':    /* Scroll right */
  145.       case 'l':
  146.       case KEY_RIGHT:
  147.         if (hscroll < MAX_LEN)
  148.           hscroll++;
  149.         break;
  150.       case ESC:
  151.         break;
  152.     }
  153.   }
  154.  
  155.   delwin(dialog);
  156.   fclose(fd);
  157.   return -1;    /* ESC pressed */
  158. }
  159. /* End of dialog_tailbox() */
  160.  
  161.  
  162. /*
  163.  * Display text from a file in a dialog box in background, like in a "tail -f &".
  164.  */
  165. void dialog_tailboxbg(const char *title, const char *file, int height, int width, int cant_kill)
  166. {
  167.   int x, y;
  168.   WINDOW *dialog, *text;
  169.   char ch;
  170.  
  171.   auto_sizefile(file, &height, &width, 1, 0);
  172.   print_size(height, width);
  173.   ctl_size(height, width);
  174.  
  175.   /* Open input file for reading */
  176.   if ((fd = fopen(file, "rb")) == NULL)
  177.     exiterr("\nCan't open input file in dialog_tailboxbg().\n");
  178.  
  179.   if (begin_set == 1) {
  180.     x = begin_x;
  181.     y = begin_y;
  182.   } else {
  183.     /* center dialog box on screen */
  184.     x = (SCOLS - width)/2;
  185.     y = (SLINES - height)/2;
  186.   }
  187.  
  188. #ifdef HAVE_NCURSES
  189.   if (use_shadow)
  190.     draw_shadow(stdscr, y, x, height, width);
  191. #endif
  192.   dialog = newwin(height, width, y, x);
  193.   keypad(dialog, FALSE);
  194. /*  leaveok(dialog, TRUE);
  195. */
  196.   /* Create window for text region, used for scrolling text */
  197.   text = subwin(dialog, height-2, width-2, y+1, x+1);
  198.   keypad(text, FALSE);
  199. /*  leaveok(text, TRUE);
  200. */
  201.   draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
  202.  
  203.   if (title != NULL) {
  204.     wattrset(dialog, title_attr);
  205.     wmove(dialog, 0, (width - strlen(title))/2 - 1);
  206.     waddch(dialog, ' ');
  207.     waddstr(dialog, title);
  208.     waddch(dialog, ' ');
  209.   }
  210.  
  211.   wmove(dialog, height-2, 2);
  212.   
  213.   wnoutrefresh(dialog);
  214.  
  215.   /* Print last page of text */
  216.   attr_clear(text, height-2, width-2, dialog_attr);
  217.   print_last_page(text, height-3, width-2);
  218.   wrefresh_lock_tailbg(dialog);
  219.  
  220.   if (cant_kill)
  221.     signal(15, &signal_tailbg);
  222.  
  223.   while (!can_quit) {
  224.     ch=getc(fd);
  225.     ungetc(ch, fd);
  226.     if ((ch != -1) || (hscroll != old_hscroll)) {
  227.       old_hscroll=hscroll;
  228.       print_last_page(text, height-2-1, width-2);
  229.       wrefresh_lock_tailbg(dialog);
  230.     }
  231.     sleep(1);
  232.   }
  233. }
  234. /* End of dialog_tailboxbg() */
  235.  
  236.  
  237. /*
  238.  * Go back 'n' lines in text file. BUF_SIZE has to be in 'size_t' range.
  239.  */
  240. static void last_lines(int n)
  241. {
  242.   int i=0;
  243.   static char *ptr, buf[BUF_SIZE+1];
  244.   size_t size_to_read;
  245.   long fpos;
  246.  
  247.   if (fseek(fd, 0, SEEK_END) == -1)
  248.     exiterr("\nError moving file pointer in last_lines().\n");
  249.  
  250.   if ((fpos=ftell(fd)) >= BUF_SIZE) {
  251.     if (fseek(fd, -BUF_SIZE, SEEK_END) == -1)
  252.       exiterr("\nError moving file pointer in last_lines().\n");
  253.  
  254.     size_to_read=(size_t) BUF_SIZE;
  255.   } else {
  256.     if (fseek(fd, 0, SEEK_SET) == -1)
  257.       exiterr("\nError moving file pointer in last_lines().\n");
  258.  
  259.     size_to_read=((size_t)fpos);
  260.   }
  261.   fread(buf, size_to_read, 1, fd);
  262.   if (ferror(fd))
  263.     exiterr("\nError reading file in last_lines().\n");
  264.  
  265.   ptr = buf+size_to_read;    /* here ptr points to (last char of buf)+1 = eof */
  266.  
  267.   while (i++ <= n)
  268.     while ( *(--ptr) != '\n' )
  269.       if ( ptr <= buf )
  270.         if ( size_to_read == BUF_SIZE ) /* buffer full */
  271.           exiterr("\nError reading file in last_lines(): Line too long. \n");
  272.         else {
  273.           ptr=buf-1;
  274.           i=n+1;
  275.           break;
  276.         }
  277.   ptr++;
  278.  
  279.   if (fseek(fd, fpos-(buf+size_to_read-ptr), SEEK_SET) == -1)
  280.     exiterr("\nError moving file pointer in last_lines().\n");
  281. }
  282. /* End of last_lines() */
  283.  
  284. /*
  285.  * Print a new page of text. Called by dialog_tailbox().
  286.  */
  287. static void print_page(WINDOW *win, int height, int width)
  288. {
  289.   int i, passed_end = 0;
  290.  
  291.   page_length = 0;
  292.   for (i = 0; i < height; i++) {
  293.     print_line(win, i, width);
  294.     if (!passed_end)
  295.       page_length++;
  296.     if (end_reached && !passed_end)
  297.       passed_end = 1;
  298.   }
  299.   wnoutrefresh(win);
  300. }
  301. /* End of print_page() */
  302.  
  303. static void print_last_page(WINDOW *win, int height, int width)
  304. {
  305.   last_lines(height);
  306.   print_page(win, height, width);
  307. }
  308.  
  309. /*
  310.  * Print a new line of text. Called by dialog_tailbox() and print_page().
  311.  */
  312. static void print_line(WINDOW *win, int row, int width)
  313. {
  314.   int i, y, x;
  315.   char *line;
  316.  
  317.   line = get_line();
  318.   line += MIN(strlen(line),hscroll);    /* Scroll horizontally */
  319.   wmove(win, row, 0);    /* move cursor to correct line */
  320.   waddch(win,' ');
  321. #ifdef HAVE_NCURSES
  322.   waddnstr(win, line, MIN(strlen(line),width-2));
  323. #else
  324.   line[MIN(strlen(line),width-2)] = '\0';
  325.   waddstr(win, line);
  326. #endif
  327.  
  328.   getyx(win, y, x);
  329.   /* Clear 'residue' of previous line */
  330.   for (i = 0; i < width-x; i++)
  331.     waddch(win, ' ');
  332. }
  333. /* End of print_line() */
  334.  
  335.  
  336. /*
  337.  * Return current line of text. Called by dialog_tailbox() and print_line().
  338.  * 'page' should point to start of current line before calling, and will be
  339.  * updated to point to start of next line.
  340.  */
  341. static char *get_line(void) 
  342.   int i = 0, j, tmpint;
  343.   static char line[MAX_LEN+1], ch;
  344.  
  345.   end_reached = 0;
  346.  
  347.   do {
  348.     if (((ch = getc(fd)) == EOF) && !feof(fd))
  349.       exiterr("\nError moving file pointer in get_line().\n");
  350.     else if ((i < MAX_LEN) && !feof(fd) && (ch != '\n'))
  351.       if ((ch == TAB) && (tab_correct)) {
  352.         tmpint=tab_len-(i%tab_len);
  353.         for (j = 0; j < tmpint; j++)
  354.           if (i < MAX_LEN)
  355.             line[i++]=' ';
  356.       } else line[i++] = ch;
  357.   } while (!feof(fd) && (ch != '\n'));
  358.   
  359.   line[i++]='\0';
  360.  
  361.   if (feof(fd)) end_reached=1;
  362.  
  363.   return line;
  364. }  
  365. /* End of get_line() */
  366.